package com.burst.reptile.modular.common;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.burst.reptile.common.constant.Constants;
import com.burst.reptile.common.constant.HttpStatus;
import com.burst.reptile.common.utils.SecurityUtils;
import com.burst.reptile.common.utils.ToolUtil;
import com.burst.reptile.common.utils.file.FileUploadUtils;
import com.burst.reptile.common.utils.file.FileUtils;
import com.burst.reptile.common.utils.file.ImgUtils;
import com.burst.reptile.common.utils.file.VideoUtils;
import com.burst.reptile.framework.config.CrawlerConfig;
import com.burst.reptile.framework.config.ServerConfig;
import com.burst.reptile.framework.redis.RedisCache;
import com.burst.reptile.framework.tencent.CosPutObject;
import com.burst.reptile.framework.web.result.Result;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;

/**
 * 通用请求处理
 * 
 * @author wujin
 * @date: 2020年5月28日 下午2:32:47
 */
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CommonController {

	private static final Logger log = LoggerFactory.getLogger(CommonController.class);

	private final ServerConfig serverConfig;
	
	private final CosPutObject cosPutObject;
	
	private final RedisCache redisCache;

	/**
	 * 导出文件通用下载请求
	 * 
	 * @param fileName 文件名称
	 * @param delete   是否删除
	 */
	@GetMapping("/common/download")
	public void fileDownload(String fileName, Boolean delete, HttpServletResponse response,
			HttpServletRequest request) {
		try {
			if (!FileUtils.isValidFilename(fileName)) {
				throw new Exception(StrUtil.format("文件名称({})非法，不允许下载。 ", fileName));
			}
			String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
			String filePath = CrawlerConfig.getDownloadPath() + fileName;
			response.setCharacterEncoding("utf-8");
			response.setContentType("multipart/form-data");
			response.setHeader("Content-Disposition",
					"attachment;fileName=" + FileUtils.setFileDownloadHeader(request, realFileName));
			FileUtils.writeBytes(filePath, response.getOutputStream());
			if (delete) {
				FileUtils.deleteFile(filePath);
			}
		} catch (Exception e) {
			log.error("下载文件失败", e);
		}
	}

	/**
	 * 通用上传请求
	 */
	@PostMapping("/common/upload")
	public Result<Object> uploadFile(MultipartFile file) throws Exception {
		try {
			// 上传文件路径
			String filePath = CrawlerConfig.getUploadPath();
			// 上传并返回新文件名称
			String fileName = FileUploadUtils.upload(filePath, file);
			String url = serverConfig.getUrl() + "/common/download/resource?name=" + fileName;
			Map<String, String> map = new HashMap<>();
			String downloadName = StrUtil.subAfter(fileName, "/", true);
			map.put("fileName", downloadName);
			map.put("url", url);
			return Result.success(map);
		} catch (Exception e) {
			return Result.error(e.getMessage());
		}
	}

	/**
	 * layui富文本文件上传
	 */
	@PostMapping("/common/layuiupload")
	public Result<Object> layuiupload(MultipartFile file) throws Exception {
		try {
			// 上传文件路径
			String filePath = CrawlerConfig.getUploadPath();
			// 上传并返回新文件名称
			String fileName = FileUploadUtils.upload(filePath, file);
			String url = serverConfig.getUrl() + "/common/download/resource?name=" + fileName;
			Map<String, String> map = new HashMap<>();
			map.put("title", StrUtil.subAfter(fileName, "/", true));
			map.put("src", url);
			return Result.success(map);
		} catch (Exception e) {
			return Result.error(e.getMessage());
		}
	}

	/**
	 * 本地资源通用下载
	 */
	@GetMapping("/common/download/resource")
	public void resourceDownload(String name, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// 本地资源路径
		String localPath = CrawlerConfig.getProfile();
		response.setCharacterEncoding("utf-8");
		response.setContentType("multipart/form-data");
        // 数据库资源地址
		String downloadPath = localPath + StrUtil.subAfter(name, Constants.RESOURCE_PREFIX, false);
        // 下载名称
        String downloadName = StrUtil.subAfter(downloadPath, "/", true);
		response.setHeader("Content-Disposition",
				"attachment;fileName=" + FileUtils.setFileDownloadHeader(request, downloadName));
		FileUtils.writeBytes(downloadPath, response.getOutputStream());
	}
	
	/**
	 * 上传图片到腾讯云COS
	 * @param uploadFile
	 * @param request
	 * @return
	 * @throws IOException 
	 * @throws IllegalStateException 
	 */
	@PostMapping("/common/helpimg")
	public Result<Object> helpimg(MultipartFile uploadFile, HttpServletRequest request) throws IllegalStateException, IOException {
		if(ToolUtil.isEmpty(uploadFile)) {
			return Result.error(HttpStatus.BAD_REQUEST, "请上传文件");
		}
		String bucketName = CrawlerConfig.getBucketName();
		String extension = FileUploadUtils.getExtension(uploadFile);
		String fileName = IdUtil.simpleUUID() + "." + extension;
		String key = Constants.IMG_KEY + fileName;
		cosPutObject.put(uploadFile, CrawlerConfig.getBucketName(), key, IdUtil.simpleUUID());
        return Result.success(Constants.HTTPS + bucketName + "." + CrawlerConfig.getDomainName() + "/" + Constants.IMG_KEY + fileName);
	}
	
	/**
	 * 上传图片到腾讯云COS
	 * @param uploadFile
	 * @param request
	 * @return
	 * @throws IOException 
	 * @throws IllegalStateException 
	 */
	@PostMapping("/common/img")
	public Result<Object> img(MultipartFile uploadFile, HttpServletRequest request, @RequestParam String uuid) throws IllegalStateException, IOException {
		if(ToolUtil.isEmpty(uploadFile)) {
			return Result.error(HttpStatus.BAD_REQUEST, "请上传文件");
		}
		String bucketName = CrawlerConfig.getBucketName();
		Long loginUserId = SecurityUtils.getLoginUserId();
		String extension = FileUploadUtils.getExtension(uploadFile);
		String fileName = IdUtil.simpleUUID() + "." + extension;
		String key = Constants.IMG_KEY + fileName;
		String redisKey = Constants.UPLOAD_PROGRESS + loginUserId + ":" + uuid;
		cosPutObject.put(uploadFile, CrawlerConfig.getBucketName(), key, redisKey);
		redisCache.deleteObject(redisKey);
		redisCache.deleteObject(redisKey + "_percentage");
        return Result.success(Constants.HTTPS + bucketName + "." + CrawlerConfig.getDomainName() + "/" + Constants.IMG_KEY + fileName);
	}
	
	/**
	 * tinymce 上传图片到腾讯云COS
	 * @param uploadFile
	 * @param request
	 * @return
	 * @throws IOException 
	 * @throws IllegalStateException 
	 */
	@PostMapping("/common/tinyimg")
	public Result<Object> tinyimg(MultipartFile uploadFile, HttpServletRequest request, @RequestParam String uuid) throws IllegalStateException, IOException {
		if(ToolUtil.isEmpty(uploadFile)) {
			return Result.error(HttpStatus.BAD_REQUEST, "请上传文件");
		}
		String bucketName = CrawlerConfig.getBucketName();
		String extension = FileUploadUtils.getExtension(uploadFile);
		String fileName = IdUtil.simpleUUID() + "." + extension;
		String key = Constants.IMG_KEY + fileName;
		boolean watermark = CrawlerConfig.getWatermark();
		if(watermark) {
			String uploadPath = CrawlerConfig.getUploadPath();
			String destImageFile = uploadPath + File.separator + IdUtil.simpleUUID() + "." + extension;
			// 上传文件路径
			String filePath = uploadPath + File.separator + fileName;
			// 保存
			uploadFile.transferTo(new File(filePath));
			ImgUtils.myPressImage(filePath, destImageFile, CrawlerConfig.getPressImgFile());
			cosPutObject.localPut(destImageFile, CrawlerConfig.getBucketName(), key);
			File desFile = new File(destImageFile);
			if(desFile.exists()) {
				desFile.delete();
			}
		}else {
			cosPutObject.put(uploadFile, bucketName, key, uuid);
		}
        return Result.success(Constants.HTTPS + bucketName + "." + CrawlerConfig.getDomainName() + "/" + Constants.IMG_KEY + fileName);
	}
	
	/**
	 * tinymce 上传音视频到腾讯云COS
	 * @param uploadFile
	 * @param request
	 * @return
	 */
	@PostMapping("/common/video")
	public Result<Object> tinyvideo(MultipartFile uploadFile, @RequestParam String uuid) {
		if(ToolUtil.isEmpty(uploadFile)) {
			return Result.error(HttpStatus.BAD_REQUEST, "请上传文件");
		}
		String bucketName = CrawlerConfig.getBucketName();
		Long loginUserId = SecurityUtils.getLoginUserId();
		String extension = FileUploadUtils.getExtension(uploadFile);
		String fileName = IdUtil.simpleUUID() + "." + extension;
		String key = Constants.VIDEO_KEY + fileName;
		String redisKey = Constants.UPLOAD_PROGRESS + loginUserId + ":" + uuid;
		String etag = cosPutObject.put(uploadFile,bucketName , key, redisKey);
		Map<String, String> map = new HashMap<>();
		String url = Constants.HTTPS + bucketName + "." + CrawlerConfig.getDomainName() + "/" + Constants.VIDEO_KEY + fileName;
		map.put("videoUrl", url);
		String mediaPicPath = CrawlerConfig.getImgCoverPath() + IdUtil.simpleUUID() + ".jpg";
		//截取封面图
		try {
			VideoUtils.fetchFrameUrl(url, mediaPicPath, 1);
			String imgFileName = IdUtil.simpleUUID() + ".jpg";
			String imgkey = Constants.IMG_KEY + imgFileName;
			cosPutObject.localPut(mediaPicPath, bucketName, imgkey);
			String coverUrl = Constants.HTTPS + bucketName + "." + CrawlerConfig.getDomainName() + "/" + Constants.IMG_KEY + imgFileName;
			map.put("coverUrl", coverUrl);
			map.put("videoId", etag);
			File file = new File(mediaPicPath);
			if(file.exists()) {
				file.delete();
			}
		} catch (Exception e) {
			log.error("截取视频封面失败");
		}
		redisCache.deleteObject(redisKey);
		redisCache.deleteObject(redisKey + "_percentage");
        return Result.success(map);
	}
	
	/**
	 * 文件上传进度
	 * @param request
	 * @return
	 */
	@PostMapping("/uploadStatus")
    public Integer uploadStatus(HttpServletRequest request){
        HttpSession session = request.getSession();
        Object percent = session.getAttribute("upload_percent");
        return null != percent ? (Integer) percent : 0;
    }
	
	/**
	 * 上传腾讯云COS 进度查询
	 * @param request
	 * @return
	 */
	@PostMapping("/cosprogress")
    public Result<Object> cosprogress(@RequestParam String uuid){
		Long loginUserId = SecurityUtils.getLoginUserId();
		Object cacheObject = redisCache.getCacheObject(Constants.UPLOAD_PROGRESS + loginUserId + ":" + uuid + "_percentage");
		return Result.success(ToolUtil.isEmpty(cacheObject) ? 0 : cacheObject);
    }
	
}
